// This MFC Samples source code demonstrates using MFC Microsoft Office Fluent User Interface 
// (the "Fluent UI") and is provided only as referential material to supplement the 
// Microsoft Foundation Classes Reference and related electronic documentation 
// included with the MFC C++ library software.  
// License terms to copy, use or distribute the Fluent UI are available separately.  
// To learn more about our Fluent UI licensing program, please visit 
// http://msdn.microsoft.com/officeui.
//
// Copyright (C) Microsoft Corporation
// All rights reserved.

// assitDoc.cpp : implementation of the CwaiDoc class
//

#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "assit.h"
#endif
#include "assitDoc.h"
#include "assitView.h"
#include "XMLDoc.h"
#include "AssitTreeNode.h"
#include "HintView.h"
#include "MainFrm.h"
#include "ProjectMonitor.h"

#include "tinyxml2.h"
using namespace tinyxml2;

#include <propkey.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CwaiDoc

IMPLEMENT_DYNCREATE(CwaiDoc, CDocument)

BEGIN_MESSAGE_MAP(CwaiDoc, CDocument)
END_MESSAGE_MAP()


// CwaiDoc construction/destruction

CwaiDoc::CwaiDoc()
{
	// TODO: add one-time construction code here
	m_pXMLDoc = NULL;
	m_fp = NULL;
}

CwaiDoc::~CwaiDoc()
{
	OnSaveDocument(m_filePath);

	if(m_fp)
		fclose(m_fp);
	if(m_pXMLDoc)
		delete m_pXMLDoc;

	CString savePath = m_filePath + L".save";
	if( -1 == _waccess((LPCWSTR)savePath, 0))
		return;
	if(CopyFile(savePath, m_filePath, FALSE))
	{
		DeleteFile(savePath);
	}
}

BOOL CwaiDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	CProjectMonitor monitor;
	CItem item;
	item.currentDay = 2;
	item.currentProgress = 20;
	item.workDays = 8;
	monitor.AddItem(item);
	monitor.printSum();
	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
#if 0
	tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
	XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );

	XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
	for( int i=0; i<3; ++i ) {
		sub[i]->SetAttribute( "attrib", i );
	}
	element->InsertEndChild( sub[2] );
	XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
	comment->SetUserData((void*)2);
	element->InsertAfterChild( comment, sub[0] );
	element->InsertAfterChild( sub[0], sub[1] );
	sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
	doc->Print();
	doc->SaveFile( "D:\\1.xml" );
	delete doc;

	CXMLDoc xmlDoc;
	xmlDoc.initialize();
	XMLNode* root = xmlDoc.getRoot();
	XMLNode* list1 = xmlDoc.insertSub(root, "list1");
	XMLNode* list1_1 = xmlDoc.insertSub(list1, "list1.1");
	xmlDoc.insertSub(list1_1, "list1.1.1");
	xmlDoc.insertSub(list1, "list1.2");
	xmlDoc.insertSub(root, "list2");
	xmlDoc.saveDoc("D:\\out.xml");
#endif

	return TRUE;
}




// CwaiDoc serialization

void CwaiDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

#ifdef SHARED_HANDLERS

// Support for thumbnails
void CwaiDoc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
{
	// Modify this code to draw the document's data
	dc.FillSolidRect(lprcBounds, RGB(255, 255, 255));

	CString strText = _T("TODO: implement thumbnail drawing here");
	LOGFONT lf;

	CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
	pDefaultGUIFont->GetLogFont(&lf);
	lf.lfHeight = 36;

	CFont fontDraw;
	fontDraw.CreateFontIndirect(&lf);

	CFont* pOldFont = dc.SelectObject(&fontDraw);
	dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK);
	dc.SelectObject(pOldFont);
}

// Support for Search Handlers
void CwaiDoc::InitializeSearchContent()
{
	CString strSearchContent;
	// Set search contents from document's data. 
	// The content parts should be separated by ";"

	// For example:  strSearchContent = _T("point;rectangle;circle;ole object;");
	SetSearchContent(strSearchContent);
}

void CwaiDoc::SetSearchContent(const CString& value)
{
	if (value.IsEmpty())
	{
		RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
	}
	else
	{
		CMFCFilterChunkValueImpl *pChunk = NULL;
		ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
		if (pChunk != NULL)
		{
			pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
			SetChunkValue(pChunk);
		}
	}
}

#endif // SHARED_HANDLERS

// CwaiDoc diagnostics

#ifdef _DEBUG
void CwaiDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CwaiDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG


// CwaiDoc commands

static bool travelTree(XMLNode* pNode)
{
	XMLNode* pChildNode = pNode->FirstChild();
	while(pChildNode)
	{
		if(travelTree(pChildNode))
			return true;
		pChildNode = pChildNode->NextSibling();
	}

	XMLElement* pElement = pNode->ToElement();
	if(!pElement) return false;

	//It's done, return.
	if(pElement->BoolAttribute("checked")) return false;
	const char* content = pElement->Attribute("content");
	const char* pStr = strstr(content, "<D>");
	if(pStr)
	{
		const char* pStr2 = strstr(pStr,"</D>");
		if(pStr2)
		{
			std::string sdate = std::string(pStr+3, pStr2-pStr-3);
			const char* cdate = sdate.c_str();
			const char* pos1 = strchr(cdate, '-');
			std::string syear = std::string(cdate, pos1-cdate);
			const char* pos2 = strchr(pos1+1, '-');
			std::string smonth = std::string(pos1+1, pos2-(pos1+1));
			const char* pos3 = cdate + sdate.size();
			std::string sday = std::string(pos2+1, pos3-(pos2+1));

			int year = atoi(syear.c_str());
			int month = atoi(smonth.c_str());
			int day = atoi(sday.c_str());

			CTime time(year, month, day, 0, 0, 0);
			if(time < CTime::GetCurrentTime())
			{
				CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd();
				// View
				CwaiView *pView= (CwaiView *)pMain->getMainView();
				CDC* pDC = pView->GetDC();
				CRect rect;
				pDC->GetClipBox(rect);
				pView->ReleaseDC(pDC);
				int top = rect.top+rect.Height()/2;
				CRect rectCenter(0, top, rect.Width(), top+200);

				CRuntimeClass* pViewClass=RUNTIME_CLASS(CHintView); 
				CHintView* pHintView=(CHintView*)pViewClass->CreateObject();
				BOOL ret = pHintView->Create( NULL, L"View", WS_CHILD|WS_VISIBLE, 
					rectCenter, pView, GetWindowID() );

				int nChar = MultiByteToWideChar(CP_UTF8, 0, content, strlen(content), NULL, 0);
				wchar_t* wchs = new wchar_t[nChar+1];
				wchs[nChar] = 0;
				MultiByteToWideChar(CP_UTF8, 0, content, strlen(content), wchs, nChar);
				pHintView->setHint(CString(wchs));
				delete[] wchs;

				pHintView->ShowWindow(SW_SHOW);
			}
			return TRUE;
		}
	}
}

void CwaiDoc::CheckToRemind()
{
	if(!m_pXMLDoc)
		return;
	XMLNode* pNode = m_pXMLDoc->getRoot();
	if(!pNode) return;
	travelTree(pNode);

}

BOOL CwaiDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;

	if(m_fp)
	{
		fclose(m_fp);
		m_fp = NULL;
	}
	delete m_pXMLDoc;
	m_pXMLDoc = new CXMLDoc();
	m_fp = _wfopen(lpszPathName, L"rb");
	if(m_fp)
		m_pXMLDoc->LoadFile(m_fp);

	CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd();
    // View
	CwaiView *pView= (CwaiView *)pMain->getMainView();
	pView->buildTree(m_pXMLDoc->getRoot(), NULL);
	pView->reloadTreeData();

	m_filePath = CString(lpszPathName);

	CheckToRemind();

	return TRUE;
}


BOOL CwaiDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
	// TODO: Add your specialized code here and/or call the base class
	if(!m_pXMLDoc) return FALSE;

	//In case that there is uncommitted content.
	HWND hWnd = GetFocus();
	CWnd* pWnd = CWnd::FromHandle(hWnd);
	if(pWnd)
	{
		pWnd->SendMessage(WM_KILLFOCUS, 0, 0);
	}

	CString savePath = CString(lpszPathName);
	if(savePath.IsEmpty())
		savePath  = L"D:\\1.xml";
	if(m_filePath == savePath)
	{
		savePath += L".save";
	}
	//Save the current document to a file path.
	FILE* fp = _wfopen((LPCWSTR)savePath, L"wb");
	if(fp)
		m_pXMLDoc->saveFile(fp);
	fclose(fp);

	return TRUE;
	//return CDocument::OnSaveDocument(lpszPathName);
}
